from datetime import datetime, timedelta
from flask import Blueprint, render_template, request, current_app, jsonify
from applications.common.curd import model_to_dicts
from applications.common.helper import ModelFilter
from applications.common.utils.http import table_api, success_api, fail_api
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import CourseActionResponse, PointActionResponse, ResponseResult, PoliceModels
from applications.schemas import ActionresponseSchema, PointActionResponseSchema, ResponseResultSchema, PoliceOutSchema, \
    ResponseResultSchema

course_actionresponse_bp = Blueprint('courseActionresponse', __name__, url_prefix='/course/actionresponse')


@course_actionresponse_bp.get('/')
def main():
    return render_template('admin/course/actionresponse/main.html')


@course_actionresponse_bp.get('/data')
def data():
    # 获取请求参数
    course_name = xss_escape(request.args.get('course_name', type=str))
    # 查询参数构造
    mf = ModelFilter()
    if course_name:
        mf.contains(field_name="course_name", value=course_name)

    # orm查询
    # 使用分页获取data需要.items
    train = CourseActionResponse.query.filter(mf.get_filter(model=CourseActionResponse)).filter_by(
        del_flag=0).with_entities(
        CourseActionResponse.course_id,
        CourseActionResponse.course_name,
        CourseActionResponse.course_description,
        CourseActionResponse.course_length,
        CourseActionResponse.course_loadtime,
        CourseActionResponse.course_updatetime).layui_paginate()
    data = model_to_dicts(schema=ActionresponseSchema, data=train.items)
    count = train.total
    # 返回api
    return table_api(data=data, count=count)


@course_actionresponse_bp.get('/add')
def getAddPage():
    return render_template('admin/course/actionresponse/add.html')


@course_actionresponse_bp.get('/cover')
def getCoverPage():
    return render_template('admin/course/actionresponse/cover.html')


@course_actionresponse_bp.post('/add')
def postAdd():
    course = request.json
    try:
        course_name = course['course_name']
        icon_path = str(course['course_icon'])
        course_description = course['course_description']
        course_length = course['course_length']
        video_path = course['video_path']
    except KeyError:
        return fail_api(msg="课程信息参数缺失，请检查参数")
    # 根据图片url找到本地图片，打开为二进制文件
    try:
        with open('.' + icon_path.replace('_uploads/icons', current_app.config.get("UPLOADED_ICONS_DEST")), 'rb') as f:
            image_data = f.read()
    except FileNotFoundError:
        res = {
            "msg": "找不到图片",
            "code": 1,
            "success": False
        }
        return jsonify(res)
    courseActionresponse = CourseActionResponse(
        course_name=course_name,
        course_icon=image_data,
        course_description=course_description,
        course_length=course_length,
        course_path=video_path,
        icon_path=icon_path,
        del_flag=0
    )
    db.session.add(courseActionresponse)
    db.session.commit()
    res = {
        "msg": "上传成功",
        "code": 0,
        "success": True,
        "data":
            {"course_id": courseActionresponse.course_id}
    }
    return jsonify(res)


@course_actionresponse_bp.post('/keypoint')
def submitKeypoint():
    data = request.json
    try:
        course_id = data['course_id']
        keypoints = data['key_points']
        for keypoint in keypoints:
            startMills = time_to_milliseconds(keypoint['start']) + int(keypoint['startMills'])
            endMills = time_to_milliseconds(keypoint['end']) + int(keypoint['endMills'])
            pointActionResponse = PointActionResponse(course_id=course_id,
                                                      start_time=startMills,
                                                      end_time=endMills,
                                                      action_id=PointActionResponse.action_name_dict[
                                                          keypoint['action']],
                                                      scene_des=keypoint['description'])
            db.session.add(pointActionResponse)
    except KeyError:
        return fail_api(msg="已创建课程，关键帧参数错误，关键帧创建失败，请到编辑页面重新创建关键帧")
    try:
        db.session.commit()
    except:
        return fail_api(msg="已创建课程，关键帧创建失败，请到编辑页面重新创建关键帧")
    return success_api()


@course_actionresponse_bp.get('/edit/<int:course_id>')
def getEditPage(course_id):
    courseActionResponse = CourseActionResponse.query.filter_by(course_id=course_id, del_flag=0).with_entities(
        CourseActionResponse.course_id,
        CourseActionResponse.course_name,
        CourseActionResponse.course_description,
        CourseActionResponse.course_length,
        CourseActionResponse.course_loadtime,
        CourseActionResponse.course_updatetime,
        CourseActionResponse.course_path,
        CourseActionResponse.icon_path).one_or_none()
    if not courseActionResponse:
        return fail_api(msg='找不到该课程')
    keypoints = model_to_dicts(schema=PointActionResponseSchema,
                               data=PointActionResponse.query.filter_by(course_id=course_id).all())
    return render_template('admin/course/actionresponse/edit.html', courseActionResponse=courseActionResponse,
                           keypoints=keypoints)


@course_actionresponse_bp.post('/edit')
def saveEdit():
    try:
        data = request.json
        course = data['courseInfo']
        keypoints = data['keypoints']
        deletedPoints = data['deletedPoints']
        course_id = course['course_id']
        course_name = course['course_name']
        course_description = course['course_description']
        course_length = course['course_length']
        course_path = course['video_path']
        icon_path = str(course['course_icon'])
    except:
        return fail_api(msg="参数错误，更新失败")
    courseActionResponse = CourseActionResponse.query.filter_by(course_id=course_id, del_flag=0).one_or_none()
    if not courseActionResponse:
        return fail_api(msg="找不到该课程")
    # 如果课程封面路径发生变化，则需要打开新图片，存储二进制文件
    if not courseActionResponse.icon_path == course['course_icon']:
        try:
            with open('.' + icon_path.replace('_uploads/icons', current_app.config.get("UPLOADED_ICONS_DEST")),
                      'rb') as f:
                image_data = f.read()
                courseActionResponse.course_icon = image_data
                courseActionResponse.icon_path = course['course_icon']
        except FileNotFoundError:
            return fail_api(msg="课程封面不存在")

    courseActionResponse.course_name = course_name
    courseActionResponse.course_description = course_description
    courseActionResponse.course_length = course_length
    courseActionResponse.course_path = course_path
    courseActionResponse.course_updatetime = datetime.now()

    # 删除被删除的关键帧
    deletedKeypoints = PointActionResponse.query.filter(PointActionResponse.point_id.in_(deletedPoints)).all()
    for point in deletedKeypoints:
        db.session.delete(point)

    # 更新关键帧及插入关键帧
    keypointList = PointActionResponse.query.filter_by(course_id=course_id).all()

    try:
        for point in keypoints:
            if 'point_id' in point:
                for p in keypointList:
                    if p.point_id == point['point_id']:
                        p.start_time = time_to_milliseconds(point['start']) + int(point['startMills'])
                        p.end_time = time_to_milliseconds(point['end']) + int(point['endMills'])
                        p.action_id = PointActionResponse.action_name_dict[point['action']]
                        p.scene_des = point['description']
                        break
            else:
                pointActionResponse = PointActionResponse(course_id=course['course_id'],
                                                          start_time=time_to_milliseconds(point['start'])
                                                                     + int(point['startMills']),
                                                          end_time=time_to_milliseconds(point['end'])
                                                                   + int(point['endMills']),
                                                          action_id=PointActionResponse.action_name_dict[
                                                              point['action']],
                                                          scene_des=point['description'])
                db.session.add(pointActionResponse)
    except:
        return fail_api(msg="关键帧缺失参数，更新失败")
    try:
        db.session.commit()
    except:
        return fail_api(msg="更新失败")
    return success_api(msg="修改信息成功")


@course_actionresponse_bp.delete('/remove/<int:course_id>')
def delete(course_id):
    courseActionResponse = CourseActionResponse.query.filter_by(course_id=course_id, del_flag=0).one_or_none()
    if not courseActionResponse:
        return fail_api("该课程不存在")
    courseActionResponse.del_flag = 1
    db.session.commit()
    return success_api("删除成功")


# 多个删除
@course_actionresponse_bp.delete('/batchRemove')
def batch_remove():
    try:
        ids = list(map(int, request.form.getlist('ids[]')))
    except:
        return fail_api(msg="找不到参数")
    courses = CourseActionResponse.query.filter(CourseActionResponse.course_id.in_(ids)).all()
    for course in courses:
        course.del_flag = 1
    db.session.commit()
    return success_api(msg="删除成功")


@course_actionresponse_bp.get('/result')
def getResultPage():
    return render_template('admin/course/actionresponse/result.html')





@course_actionresponse_bp.get('/result/detail/<int:student_id>')
def result_details(student_id):
    # 获取请求参数
    course_Name = xss_escape(request.args.get('course_Name', type=str))

    # 查询参数构造
    mf = ModelFilter()
    if course_Name:
        mf.contains(field_name="course_Name", value=course_Name)

    results = ResponseResult.query.order_by('train_time').filter_by(student_id=student_id).layui_paginate()
    results_dict = model_to_dicts(schema=ResponseResultSchema, data=results.items)
    for result in results_dict:
        course = CourseActionResponse.query.filter_by(course_id=result['course_id']).with_entities(
            CourseActionResponse.course_id,
            CourseActionResponse.course_name,
            CourseActionResponse.course_description,
            CourseActionResponse.course_path,
            CourseActionResponse.course_length,
            CourseActionResponse.course_loadtime,
            CourseActionResponse.course_updatetime,
            CourseActionResponse.icon_path).one_or_none()
        if course is not None:
            result['course_name'] = course.course_name
    count = results.total
    return render_template('admin/course/actionresponse/result_detail.html', data=results_dict, count=count)


@course_actionresponse_bp.delete('/result/remove/<int:grade_id>')
def result_remove(grade_id):
    result = ResponseResult.query.filter_by(grade_id=grade_id).delete()
    db.session.commit()
    return success_api()


@course_actionresponse_bp.delete('/result/batchRemove')
def result_batch_remove():
    try:
        ids = list(map(int, request.form.getlist('ids[]')))
    except:
        return fail_api(msg="找不到参数")
    results = ResponseResult.query.filter(ResponseResult.grade_id.in_(ids)).delete()
    db.session.commit()
    return success_api()


# 时分秒时间（HH:mm:ss）转毫秒
def time_to_milliseconds(time_str):
    # 将时间字符串解析为时间对象
    time_obj = datetime.strptime(time_str, "%H:%M:%S")
    # 计算时间对象的总毫秒数
    total_milliseconds = (time_obj - datetime(1900, 1, 1)) // timedelta(milliseconds=1)
    return total_milliseconds


@course_actionresponse_bp.get('/result/detail/detail/<int:grade_id>')
def result_detail_details(grade_id):
    result = ResponseResult.query.filter_by(grade_id=grade_id).one_or_none()
    if result is None:
        return fail_api(msg="找不到该动作信息！")

    course = CourseActionResponse.query.filter_by(course_id=result.course_id).with_entities(
        CourseActionResponse.course_id,
        CourseActionResponse.course_name,
        CourseActionResponse.course_description,
        CourseActionResponse.course_loadtime,
        CourseActionResponse.course_updatetime).one_or_none()
    police = PoliceModels.query.filter_by(id=result.student_id).one_or_none()

    return render_template('admin/course/actionresponse/result_detail_detail.html',
                           result=result,
                           course=course,
                           police=police)
